﻿package mortal.game.scene3D.ai.ais
{
    import Message.Public.*;
    import flash.events.*;
    import flash.geom.*;
    import frEngine.event.*;
    import mortal.game.control.subControl.*;
    import mortal.game.events.*;
    import mortal.game.mvc.*;
    import mortal.game.scene3D.ai.*;
    import mortal.game.scene3D.ai.data.*;
    import mortal.game.scene3D.events.*;
    import mortal.game.scene3D.layer3D.utils.*;
    import mortal.game.scene3D.map3D.*;
    import mortal.game.scene3D.map3D.AstarAnyDirection.*;
    import mortal.game.scene3D.map3D.AstarAnyDirection.data.*;
    import mortal.game.scene3D.map3D.util.*;
    import mortal.game.scene3D.player.entity.*;
    import mortal.game.utils.*;
    import mortal.game.view.guide.*;
    import mortal.mvc.core.*;

    public class FollowFightAI extends FollowAI
    {
        protected var fData:FollowFightAIData;

        public function FollowFightAI()
        {
            return;
        }// end function

        override public function start(param1:Function = null) : void
        {
            _isStoped = false;
            this.fData = _data as FollowFightAIData;
            _scene = _data.scene;
            _meRole = _data.meRole;
            _callback = param1;
            this.range = this.fData.range;
            _player = _data.target as MovePlayer;
            if (_player != null)
            {
                _player.pointChangeHandler = onTargetChangeHandler;
                _player.realPointChangeHandler = onTargetChangeHandler;
                FrEventDispatcher.instance.proxyAddEventListener(MovePlayer(_player), PlayerEvent.ENTITY_DEAD, this.onPlayerDeadHandler, false, 0, true);
            }
            FrEventDispatcher.instance.proxyAddEventListener(_meRole, PlayerEvent.ENTITY_DEAD, onEntityDead, false, 0, true);
            FrEventDispatcher.instance.proxyAddEventListener(_meRole, PlayerEvent.GIRD_WALK_END, this.onGirdWalkEnd, false, 0, true);
            FrEventDispatcher.instance.proxyAddEventListener(_meRole, PlayerEvent.WALK_END, this.onWalkEnd, false, 0, true);
            FrEventDispatcher.instance.proxyAddEventListener(_meRole, PlayerEvent.WALK_BREAK, this.onWalkBreak, false, 0, true);
            FrEventDispatcher.instance.proxyAddEventListener(_meRole, PlayerEvent.ATTACK_GAP_TIMEOUT, this.onAttackGapTimeOut, false, 0, true);
            FrEventDispatcher.instance.proxyAddEventListener(_meRole, PlayerEvent.ObstructNotFight, this.onObstructNotFightHandler);
            Dispatcher.addEventListener(EventName.FightEntityNotOnLine, this.onFightEntityNotOnLine);
            Dispatcher.addEventListener(EventName.FightTargetIsTooFar, this.onFightTargetTooFar);
            Dispatcher.addEventListener(EventName.InputPointError, this.onInputPointError);
            NetDispatcher.addCmdListener(ServerCommand.BufferUpdate, this.buffUpdateHandler);
            GuideEffect.showAutoPathStatus();
            this.updateTilePoint();
            this.onGirdWalkEnd(null);
            if (_isStoped)
            {
                return;
            }
            if (!BuffUtil.isCanRoleWalk())
            {
                this.stop();
                return;
            }
            onTargetChangeHandler();
            disposeTimer();
            startTimerChecker();
            return;
        }// end function

        private function buffUpdateHandler(param1) : void
        {
            if (this.fData == null || this.fData.skillInfo == null)
            {
                return;
            }
            if (!BuffUtil.isCanRoleFireSkill(this.fData.skillInfo))
            {
                this.stop();
            }
            return;
        }// end function

        override protected function updateTilePoint() : void
        {
            if (_targetPixPoint == null)
            {
                _targetPixPoint = new Point();
            }
            if (_player == null)
            {
                if (this.fData == null || this.fData.point == null)
                {
                    return;
                }
                _targetPixPoint.x = this.fData.point.x;
                _targetPixPoint.y = this.fData.point.y;
            }
            else
            {
                _targetPixPoint.x = _player.realX2d;
                _targetPixPoint.y = _player.realY2d;
            }
            return;
        }// end function

        override public function stop(param1:Boolean = true) : void
        {
            if (_player != null)
            {
                _player.realPointChangeHandler = null;
                _player.pointChangeHandler = null;
                FrEventDispatcher.instance.proxyRemoveEventListener(MovePlayer(_player), PlayerEvent.ENTITY_DEAD, this.onPlayerDeadHandler, false);
            }
            FrEventDispatcher.instance.proxyRemoveEventListener(_meRole, PlayerEvent.ENTITY_DEAD, onEntityDead);
            FrEventDispatcher.instance.proxyRemoveEventListener(_meRole, PlayerEvent.GIRD_WALK_END, this.onGirdWalkEnd);
            FrEventDispatcher.instance.proxyRemoveEventListener(_meRole, PlayerEvent.WALK_END, this.onWalkEnd);
            FrEventDispatcher.instance.proxyRemoveEventListener(_meRole, PlayerEvent.WALK_BREAK, this.onWalkBreak);
            FrEventDispatcher.instance.proxyRemoveEventListener(_meRole, PlayerEvent.ATTACK_GAP_TIMEOUT, this.onAttackGapTimeOut, false);
            FrEventDispatcher.instance.proxyRemoveEventListener(_meRole, PlayerEvent.ObstructNotFight, this.onObstructNotFightHandler);
            Dispatcher.removeEventListener(EventName.FightEntityNotOnLine, this.onFightEntityNotOnLine);
            Dispatcher.removeEventListener(EventName.FightTargetIsTooFar, this.onFightTargetTooFar);
            Dispatcher.removeEventListener(EventName.InputPointError, this.onInputPointError);
            NetDispatcher.removeCmdListener(ServerCommand.BufferUpdate, this.buffUpdateHandler);
            super.stop(param1);
            return;
        }// end function

        override protected function onWalkBreak(event:Event) : void
        {
            if (RolePlayer.instance.entityInfo == null || RolePlayer.instance.entityInfo.isDead || !BuffUtil.isCanRoleWalk())
            {
                this.stop();
                return;
            }
            if (this.isInRange())
            {
                this.onGirdWalkEnd(null);
                return;
            }
            this.updateTilePoint();
            this.updatePath();
            sceneMove();
            return;
        }// end function

        override protected function onGirdWalkEnd(event:Event) : void
        {
            var _loc_2:Boolean = false;
            if (this.isInRange())
            {
                _loc_2 = isVisibleTo(_targetPixPoint.x, _targetPixPoint.y);
                if (_loc_2 || _player == null || this.range > 4000 || _player is MonsterPlayer && MonsterPlayer(_player).tboss.type == EBossType._EBossTypeBarrierFight)
                {
                    if (_meRole.isMove)
                    {
                        _meRole.stopWalking();
                    }
                    this.skillFire();
                    this.stop();
                }
                else
                {
                    _nextMoveTime = -111111;
                    this.range = range / 2;
                    this.updatePath();
                    this.sceneMove();
                }
            }
            return;
        }// end function

        override public function updatePath() : void
        {
            var _loc_2:Object = null;
            var _loc_3:FollowFightAIData = null;
            var _loc_1:* = Scene3DClickProcessor.findPath(_meRole.x2d, _meRole.y2d, _targetPixPoint.x, _targetPixPoint.y, true);
            if (_loc_1.length == 0)
            {
                this.stop();
                return;
            }
            for each (_loc_2 in _loc_1)
            {
                
                if (_loc_2 is AstarTurnPoint)
                {
                    if (AutoFightAI.isWorking && AIManager.curAI is AutoFightAI && _targetPixPoint != null)
                    {
                        AutoFightAI(AIManager.curAI).addMoveTo(new Point(_targetPixPoint.x, _targetPixPoint.y), this.range);
                        _loc_3 = AIFactory.instance.outFollowFightAIData();
                        _loc_3.from(this._data);
                        AutoFightAI(AIManager.curAI).addFollowFight(_loc_3);
                        ThingUtil.selectEntity = null;
                        this.stop();
                        return;
                    }
                }
            }
            _paths = _loc_1[0] as Array;
            return;
        }// end function

        override protected function isInRange() : Boolean
        {
            var _loc_2:Number = NaN;
            this.updateTilePoint();
            try
            {
                _loc_2 = GameMapUtil.getDistance(_meRole.x2d, _meRole.y2d, _targetPixPoint.x, _targetPixPoint.y);
            }
            catch (e)
            {
            }
            var _loc_1:* = _loc_2 <= 0 || _loc_2 <= range - 10;
            return _loc_1;
        }// end function

        override protected function onWalkEnd(event:Event) : void
        {
            if (this.isInRange())
            {
                this.onGirdWalkEnd(null);
            }
            else
            {
                this.updatePath();
                sceneMove();
            }
            return;
        }// end function

        private function onPlayerDeadHandler(event:Event) : void
        {
            this.stop();
            return;
        }// end function

        protected function skillFire() : void
        {
            if (_player != null && _player is MonsterPlayer && _player.entityInfo != null && _player.entityInfo.isInBorn)
            {
                return;
            }
            Dispatcher.dispatchEvent(new DataEvent(EventName.SkillAskServerUseSkill, _data));
            return;
        }// end function

        protected function onAttackGapTimeOut(event:Event) : void
        {
            return;
        }// end function

        protected function onSkillCoolDownFinish(event:DataEvent) : void
        {
            if (this.isProcessing())
            {
                return;
            }
            return;
        }// end function

        protected function onObstructNotFightHandler(event:Event) : void
        {
            if (this.isProcessing())
            {
                return;
            }
            return;
        }// end function

        protected function onFightEntityNotOnLine(event:DataEvent) : void
        {
            if (this.isProcessing())
            {
                return;
            }
            return;
        }// end function

        protected function onFightTargetTooFar(event:DataEvent) : void
        {
            if (this.isProcessing())
            {
                return;
            }
            return;
        }// end function

        protected function onInputPointError(event:DataEvent) : void
        {
            if (this.isProcessing())
            {
                return;
            }
            return;
        }// end function

        private function isProcessing() : Boolean
        {
            return false;
        }// end function

        public static function isVisibleTo(param1:int, param2:int) : Boolean
        {
            var _loc_3:MovePlayer = null;
            if (GameMapUtil.curMapState.isPetBreakMap)
            {
                _loc_3 = ThingUtil.entityUtil.getSelfPetEntity();
            }
            else
            {
                _loc_3 = RolePlayer.instance;
            }
            var _loc_4:* = GameMapUtil.getTilePoint(param1, param2);
            if (!AstarAnyDirection.isWalkable(_loc_4.x, _loc_4.y))
            {
                return true;
            }
            var _loc_5:* = GameMapUtil.getTilePoint(_loc_3.x2d, _loc_3.y2d);
            var _loc_6:* = GeomUtil.calcDistance(_loc_4.x, _loc_4.y, _loc_5.x, _loc_5.y);
            if (_loc_6 < 4)
            {
                if (Math.abs(_loc_5.x - _loc_4.x) <= 1 && Math.abs(_loc_5.y - _loc_4.y) <= 1)
                {
                    return true;
                }
            }
            var _loc_7:* = AstarAnyDirection.getMaxVisiblePoint(_loc_5.x, _loc_5.y, _loc_4.x, _loc_4.y, AstarAnyDirection.mapData, MapNodeType.WALK_MIN_VALUE);
            if (_loc_7.x == _loc_4.x && _loc_7.y == _loc_4.y)
            {
                return true;
            }
            return false;
        }// end function

    }
}
